/*     */ package com.zimbra.cs.service.mail;
/*     */ 
/*     */ import com.google.common.base.Strings;
/*     */ import com.google.common.io.Closeables;
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.Element.Disposition;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.soap.SoapFaultException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.index.MessageHit;
/*     */ import com.zimbra.cs.index.SearchParams;
/*     */ import com.zimbra.cs.index.SearchParams.ExpandResults;
/*     */ import com.zimbra.cs.index.SortBy;
/*     */ import com.zimbra.cs.index.ZimbraHit;
/*     */ import com.zimbra.cs.index.ZimbraQueryResults;
/*     */ import com.zimbra.cs.mailbox.Conversation;
/*     */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*     */ import com.zimbra.cs.mailbox.MailItem;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxIndex;
/*     */ import com.zimbra.cs.mailbox.Message;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.service.util.ItemIdFormatter;
/*     */ import com.zimbra.soap.JaxbUtil;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import com.zimbra.soap.mail.message.SearchConvRequest;
/*     */ import com.zimbra.soap.type.ZmBoolean;
/*     */ import java.util.ArrayList;
/*     */ import java.util.EnumSet;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class SearchConv
/*     */   extends Search
/*     */ {
/*     */   private static final int CONVERSATION_FIELD_MASK = 22;
/*     */   
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  65 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  66 */     Mailbox mbox = getRequestedMailbox(zsc);
/*  67 */     OperationContext octxt = getOperationContext(zsc, context);
/*  68 */     ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
/*  69 */     SearchConvRequest req = (SearchConvRequest)JaxbUtil.elementToJaxb(request);
/*  70 */     boolean nest = ZmBoolean.toBool(req.getNestMessages(), false);
/*  71 */     Account acct = getRequestedAccount(zsc);
/*  72 */     SearchParams params = SearchParams.parse(req, zsc, acct.getPrefMailInitialSearch());
/*     */     
/*     */ 
/*  75 */     ItemId cid = new ItemId(req.getConversationId(), zsc);
/*  76 */     params.setQueryString("conv:\"" + cid.toString(ifmt) + "\" (" + params.getQueryString() + ')');
/*     */     
/*  78 */     params.setTypes(EnumSet.of(MailItem.Type.MESSAGE));
/*     */     
/*  80 */     Element response = null;
/*  81 */     if (cid.belongsTo(mbox)) {
/*  82 */       ZimbraQueryResults results = mbox.index.search(zsc.getResponseProtocol(), octxt, params);
/*     */       try {
/*  84 */         response = zsc.createElement(MailConstants.SEARCH_CONV_RESPONSE);
/*  85 */         response.addAttribute("offset", Integer.toString(params.getOffset()));
/*     */         
/*  87 */         SortBy sort = results.getSortBy();
/*  88 */         response.addAttribute("sortBy", sort.toString());
/*     */         
/*  90 */         List<Message> msgs = mbox.getMessagesByConversation(octxt, cid.getId(), sort, -1);
/*  91 */         if ((msgs.isEmpty()) && (zsc.isDelegatedRequest())) {
/*  92 */           throw ServiceException.PERM_DENIED("you do not have sufficient permissions");
/*     */         }
/*     */         
/*     */ 
/*  96 */         Conversation conv = mbox.getConversationById(octxt, cid.getId());
/*  97 */         if (conv.isTagged(Flag.FlagInfo.DELETED)) {
/*  98 */           List<Message> raw = msgs;
/*  99 */           msgs = new ArrayList();
/* 100 */           for (Message msg : raw) {
/* 101 */             if (!msg.isTagged(Flag.FlagInfo.DELETED)) {
/* 102 */               msgs.add(msg);
/*     */             }
/*     */           }
/*     */         }
/*     */         
/* 107 */         Element container = nest ? ToXML.encodeConversationSummary(response, ifmt, octxt, conv, 22) : response;
/*     */         
/* 109 */         SearchResponse builder = new SearchResponse(zsc, octxt, container, params);
/* 110 */         builder.setAllRead(conv.getUnreadCount() == 0);
/* 111 */         boolean more = putHits(octxt, ifmt, builder, msgs, results, params, conv);
/* 112 */         response.addAttribute("more", more);
/*     */         
/*     */ 
/* 115 */         builder.add(results.getResultInfo());
/*     */       } finally {
/* 117 */         Closeables.closeQuietly(results);
/*     */       }
/*     */       
/* 120 */       return response;
/*     */     }
/*     */     try
/*     */     {
/* 124 */       Element proxyRequest = zsc.createElement(MailConstants.SEARCH_CONV_REQUEST);
/* 125 */       Account target = Provisioning.getInstance().get(Key.AccountBy.id, cid.getAccountId(), zsc.getAuthToken());
/*     */       
/* 127 */       if (target != null) {
/* 128 */         params.setInlineRule(params.getInlineRule().toLegacyExpandResults(target.getServer()));
/*     */       }
/*     */       
/* 131 */       params.encodeParams(proxyRequest);
/* 132 */       proxyRequest.addAttribute("nest", nest);
/* 133 */       proxyRequest.addAttribute("cid", cid.toString());
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 141 */       String rewrittenQueryString = mbox.getRewrittenQueryString(octxt, params);
/* 142 */       proxyRequest.addAttribute("query", rewrittenQueryString, Element.Disposition.CONTENT);
/*     */       
/*     */ 
/* 145 */       response = proxyRequest(proxyRequest, context, target.getId());
/* 146 */       return response.detach();
/*     */     } catch (SoapFaultException e) {
/* 148 */       throw ServiceException.FAILURE("SoapFaultException: ", e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private boolean putHits(OperationContext octxt, ItemIdFormatter ifmt, SearchResponse resp, List<Message> msgs, ZimbraQueryResults results, SearchParams params, Conversation conv)
/*     */     throws ServiceException
/*     */   {
/* 171 */     int offset = params.getOffset();
/* 172 */     int limit = params.getLimit();
/* 173 */     int size = msgs.size() <= limit + offset ? msgs.size() - offset : limit;
/*     */     
/* 175 */     if (size > 0)
/*     */     {
/*     */ 
/*     */ 
/* 179 */       ZimbraHit[] matched = new ZimbraHit[size];
/*     */       
/* 181 */       while (results.hasNext()) {
/* 182 */         ZimbraHit hit = results.getNext();
/*     */         
/*     */ 
/* 185 */         for (int i = offset; i < offset + size; i++) {
/* 186 */           if (hit.getParsedItemID().equals(new ItemId((MailItem)msgs.get(i)))) {
/* 187 */             matched[(i - offset)] = hit;
/* 188 */             break;
/*     */           }
/*     */         }
/*     */       }
/* 192 */       SearchParams.ExpandResults expand = params.getInlineRule();
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 200 */       boolean[] expandMsgs = determineExpandedMessages(expand, matched, msgs, conv, offset, size);
/* 201 */       for (int i = offset; i < offset + size; i++) {
/* 202 */         boolean expandMsg = expandMsgs[i];
/* 203 */         if (matched[(i - offset)] != null) {
/* 204 */           resp.add(matched[(i - offset)], expandMsg);
/*     */         } else {
/* 206 */           Message msg = (Message)msgs.get(i);
/*     */           
/* 208 */           addMessageMiss(msg, resp.toElement(), octxt, ifmt, expandMsg, params);
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 213 */     return offset + size < msgs.size();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private boolean[] determineExpandedMessages(SearchParams.ExpandResults expand, ZimbraHit[] matched, List<Message> msgs, Conversation conv, int offset, int size)
/*     */     throws ServiceException
/*     */   {
/* 223 */     int numMatched = 0;
/*     */     
/* 225 */     boolean[] expandMsgs = new boolean[size];
/* 226 */     boolean forceExpandFirstMsg; boolean forceExpandFirstMsg; if ((expand == SearchParams.ExpandResults.FIRST_MSG) || (expand == SearchParams.ExpandResults.HITS_OR_FIRST_MSG) || (expand == SearchParams.ExpandResults.U_OR_FIRST_MSG) || (expand == SearchParams.ExpandResults.U1_OR_FIRST_MSG))
/*     */     {
/*     */ 
/*     */ 
/* 230 */       forceExpandFirstMsg = true;
/*     */     } else {
/* 232 */       forceExpandFirstMsg = false;
/*     */     }
/* 234 */     for (int i = offset; i < offset + size; i++) { boolean shouldExpand;
/*     */       boolean shouldExpand;
/* 236 */       if (matched[(i - offset)] != null) {
/* 237 */         numMatched++;
/* 238 */         MessageHit hit = (MessageHit)matched[(i - offset)];
/* 239 */         Message msg = hit.getMessage();
/* 240 */         boolean shouldExpand; if (expand == SearchParams.ExpandResults.FIRST) {
/* 241 */           shouldExpand = numMatched == 1; } else { boolean shouldExpand;
/* 242 */           if ((expand == SearchParams.ExpandResults.ALL) || (expand == SearchParams.ExpandResults.HITS)) {
/* 243 */             shouldExpand = true;
/*     */           } else { boolean shouldExpand;
/* 245 */             if (expand == SearchParams.ExpandResults.HITS_OR_FIRST_MSG) {
/* 246 */               forceExpandFirstMsg = false;
/* 247 */               shouldExpand = true;
/*     */             } else { boolean shouldExpand;
/* 249 */               if (expand == SearchParams.ExpandResults.UNREAD) {
/* 250 */                 shouldExpand = msg.isUnread();
/*     */               }
/* 252 */               else if (expand == SearchParams.ExpandResults.U_OR_FIRST_MSG) {
/* 253 */                 boolean shouldExpand = msg.isUnread();
/* 254 */                 if (forceExpandFirstMsg == true) forceExpandFirstMsg = !shouldExpand;
/*     */               } else { boolean shouldExpand;
/* 256 */                 if (expand == SearchParams.ExpandResults.UNREAD_FIRST) {
/* 257 */                   shouldExpand = conv.getUnreadCount() == 0 ? false : numMatched == 1 ? true : msg.isUnread();
/*     */                 } else { boolean shouldExpand;
/* 259 */                   if (expand == SearchParams.ExpandResults.U1_OR_FIRST_MSG) {
/* 260 */                     if (conv.getUnreadCount() > 0) forceExpandFirstMsg = false;
/* 261 */                     shouldExpand = conv.getUnreadCount() == 0 ? false : numMatched == 1 ? true : msg.isUnread();
/*     */                   }
/*     */                   else {
/* 264 */                     shouldExpand = expand.matches(hit.getParsedItemID());
/*     */                   }
/*     */                 }
/*     */               }
/* 268 */             } } } } else { Message msg = (Message)msgs.get(i);
/* 269 */         shouldExpand = (expand == SearchParams.ExpandResults.ALL) || (expand.matches(msg));
/*     */       }
/* 271 */       expandMsgs[(i - offset)] = shouldExpand;
/*     */     }
/*     */     
/* 274 */     if ((forceExpandFirstMsg == true) || (expand == SearchParams.ExpandResults.FIRST_MSG)) expandMsgs[0] = true;
/* 275 */     return expandMsgs;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   private Element addMessageMiss(Message msg, Element response, OperationContext octxt, ItemIdFormatter ifmt, boolean inline, SearchParams params)
/*     */     throws ServiceException
/*     */   {
/* 283 */     if ((inline) && (msg.isUnread()) && (params.getMarkRead())) {
/*     */       try
/*     */       {
/* 286 */         msg.getMailbox().alterTag(octxt, msg.getId(), msg.getType(), Flag.FlagInfo.UNREAD, false, null);
/*     */       } catch (ServiceException e) {
/* 288 */         ZimbraLog.search.warn("problem marking message as read (ignored): %d", Integer.valueOf(msg.getId()), e);
/*     */       }
/*     */     }
/*     */     
/*     */     Element el;
/* 293 */     if (inline) {
/* 294 */       Element el = ToXML.encodeMessageAsMP(response, ifmt, octxt, msg, null, params.getMaxInlinedLength(), params.getWantHtml(), params.getNeuterImages(), null, true, params.getWantExpandGroupInfo(), LC.mime_encode_missing_blob.booleanValue());
/*     */       
/* 296 */       if (!Strings.isNullOrEmpty(msg.getFragment())) {
/* 297 */         el.addAttribute("fr", msg.getFragment(), Element.Disposition.CONTENT);
/*     */       }
/*     */     } else {
/* 300 */       el = ToXML.encodeMessageSummary(response, ifmt, octxt, msg, params.getWantRecipients(), -4194305);
/*     */     }
/* 302 */     return el;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/mail/SearchConv.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */